import 'package:bwt_ad_flutter/BwtAdCore.dart';
import 'package:bwt_ad_flutter/ad/BwtAd.dart';
import 'package:bwt_ad_flutter/ad/BwtNativeExpressAd.dart';
import 'package:bwt_ad_flutter/ad/loader/BwtAdLoader.dart';
import 'package:bwt_ad_flutter/ad/loader/BwtNativeExpressAdLoader.dart';
import 'package:bwt_ad_flutter/util/UuidUtil.dart';

import '../ad/loader/BwtNativeAdLoader.dart';
import '../ad/widget/nativeWidget/BwtNativeAd.dart';
import '../ad/widget/nativeWidget/BwtNativeAdData.dart';

class BwtAdManager {
  static const _eventOnAdLoad = 'OnAdLoad';
  static const _eventOnAdFailed = 'OnAdFailed';
  static const _eventOnAdMeasured = 'OnAdMeasured';
  static const _eventOnAdExpose = 'OnAdExpose';
  static const _eventOnAdClick = 'OnAdClick';
  static const _eventOnAdClose = 'OnAdClose';

  // static const _eventOnAdRender = 'OnAdRender';
  // static const _eventOnAdReward = 'OnAdReward';

  static final List<BwtAdLoader> _adLoaderList = [];

  BwtAdManager._();

  /// 加载广告
  static loadAd({
    required BwtAdLoader bwtLoader,
    required String posId,
    required String methodName,
    Map<String, dynamic>? arguments,
  }) async {
    var contains = _adLoaderList.contains(bwtLoader);
    if (!contains) {
      _adLoaderList.add(bwtLoader);
    }
    await _loadAd(
      posId: posId,
      methodName: methodName,
      bwtLoader: bwtLoader,
      arguments: arguments,
    );
  }

  /// 释放广告
  static releaseAd({required BwtAd bwtAd}) async {
    await _releaseAd(adId: bwtAd.adId);

    var adLoaderId = bwtAd.adLoaderId;
    var adLoader = _findBwtAdLoader(adLoaderId);
    adLoader?.adList.remove(bwtAd);
  }

  /// 释放广告加载
  static releaseAdLoader({required BwtAdLoader bwtLoader}) {
    for (var bwtAd in bwtLoader.adList) {
      bwtAd.release();
    }
    _adLoaderList.remove(bwtLoader);
  }

  /// 广告事件
  static onAdEvent({required Map<dynamic, dynamic> arguments}) {
    var adLoaderId = arguments[BwtAdCore.keyAdLoaderId];
    var bwtAdLoader = _findBwtAdLoader(adLoaderId);
    if (bwtAdLoader == null) return;

    var adEvent = arguments[BwtAdCore.keyAdEvent];
    if (adEvent == null) return;

    var adId = arguments[BwtAdCore.keyAdId];
    var bwtAd = bwtAdLoader.findBwtAd(adId: adId);
    if (bwtAd == null) return;

    /// TODO 还有_eventOnAdRender、_eventOnAdReward没做
    switch (adEvent) {
      case _eventOnAdLoad:
        var method = arguments["method"];
        if (method == "loadNativeAd") {
          var nativeData = Map<String, dynamic>.from(arguments['nativeData']);
          //加载自渲染的onload 需要把自渲染数据抛给开发者
          BwtNativeAdData model = BwtNativeAdData.fromMap(nativeData);
          bwtAdLoader as BwtNativeAdLoader;
          bwtAdLoader.onNativeAdLoadCallback(bwtAd as BwtNativeAd, model);
        } else {
          bwtAdLoader.onAdLoadCallback(bwtAd);
        }
      case _eventOnAdFailed:
        bwtAdLoader.onAdFailedCallback(arguments[BwtAdCore.keyAdMsg]);
      case _eventOnAdMeasured:
        if (bwtAdLoader is BwtNativeExpressAdLoader &&
            bwtAd is BwtNativeExpressAd) {
          double adWidth = arguments[BwtAdCore.keyAdWidth] ?? 0;
          double adHeight = arguments[BwtAdCore.keyAdHeight] ?? 0;
          bwtAdLoader.onAdMeasured(bwtAd, adWidth, adHeight);
        }
        break;
      case _eventOnAdExpose:
        bwtAdLoader.onAdExposeCallback(bwtAd);
      case _eventOnAdClick:
        bwtAdLoader.onAdClickCallback(bwtAd);
      case _eventOnAdClose:
        bwtAdLoader.onAdCloseCallback(bwtAd);
    }
  }

  /// 加载广告
  static Future<bool> _loadAd({
    required String posId,
    required BwtAdLoader bwtLoader,
    required String methodName,
    Map<String, dynamic>? arguments,
  }) async {
    var bwtAd = bwtLoader.createBwtAd(
      adId: UuidUtil.uuid(),
      arguments: arguments,
    );
    bwtLoader.adList.add(bwtAd);

    var params = arguments ?? <String, dynamic>{};
    params[BwtAdCore.keyPosId] = posId;
    params[BwtAdCore.keyAdId] = bwtAd.adId;
    params[BwtAdCore.keyAdLoaderId] = bwtAd.adLoaderId;
    return invokeMethod(method: methodName, params: params);
  }

  /// 加载广告
  static Future<bool> invokeMethod({
    required String method,
    required Map<String, dynamic> params,
  }) async {
    return BwtAdCore.invokeMethod(method: method, params: params);
  }

  /// 根据adLoaderId查找BwtAdLoader
  static BwtAdLoader? _findBwtAdLoader(adLoaderId) {
    for (var value in _adLoaderList) {
      if (value.adLoaderId == adLoaderId) return value;
    }
    return null;
  }

  /// 释放广告
  static Future<bool> _releaseAd({
    required String adId,
  }) async {
    return BwtAdCore.invokeMethod(method: BwtAdCore.methodReleaseAd, params: {
      BwtAdCore.keyAdId: adId,
    });
  }
}
